﻿/// <reference path="libs/jquery-2.0.2.js" />
/// <reference path="prototypeExtensions.js" />
/// <reference path="controllers.js" />

var gameObjects = (function () {

    var GameObject = Object.create({
        init: function () {
        }
    });

    var GameField = GameObject.extend({
        init: function (selector) {
            this._super.init();
            this._element = $(selector);
            this._fieldArray = this.generateField();
            this.render();
            return this;
        },

        generateField: function () {
            var fieldArray = [];
            for (var row = 0; row < FieldRows; row++) {
                fieldArray[row] = [];
                for (var col = 0; col < FieldCols; col++) {
                    fieldArray[row][col] = 0;
                }
            }

            return fieldArray;
        },

        render: function () {
            var field = document.createDocumentFragment();

            var cell = $("<div></div>")
            .css({
                width: CellSize,
                height: CellSize,
                border: "1px solid black",
                position: "absolute"
            });

            for (var row = 0; row < FieldRows; row++) {
                for (var col = 0; col < FieldCols; col++) {
                    if (this._fieldArray[row][col] == 1) {
                        cell.css({
                            top: row * CellSize,
                            left: col * CellSize,
                            backgroundColor: CellColors[1],
                        }).clone().appendTo(field);
                    }
                    else {
                        cell.css({
                            top: row * CellSize,
                            left: col * CellSize,
                            backgroundColor: CellColors[0],
                        }).clone().appendTo(field);
                    }
                }

                this._element.append(field);
            }
        }
    });

    var Figure = GameObject.extend({
        init: function (id, color, currentRotation, x0, y0) {
            this._id = id;
            this.color = color;
            this._currentRotation = currentRotation;
            this._coords = this.initCoords(); 
            this._element = $("<div></div>");
            this._x = x0 || 3 * CellSize;
            this._y = y0 || -20;
            return this;
        },

        initCoords: function () {
            // every figure has its own function for that 
        },
    });

    var Dash = Figure.extend({
        init: function (currentRotation, x0, y0) {
            this._super.init("dash", CellColors[1], currentRotation, x0, y0);
            this._coords = Dash.initCoords();
            this._that = this;
            return this;
        },

        initCoords: function () {
            return new Array(
                [
                [0, 0, 0, 0],
                [1, 1, 1, 1],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0]
                ], [
                [0, 0, 0, 0],
                [1, 1, 1, 1],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0]
                ]);
        },

        _addHandlers: function () {
            $(document).keydown(function (ev) {
                if (ev.keyCode == 37) {
                    // Left key
                    if (engine.isLegalPosition(Dash._that._coords, Dash._that._currentRotation, Dash._that._x - CellSize, Dash._that._y)) {
                        Dash._x -= CellSize;
                    }
                }
                else if (ev.keyCode == 39) {
                    // Right key
                    if (engine.isLegalPosition(Dash._that._coords, Dash._that._currentRotation, Dash._that._x + CellSize, Dash._that._y)) {
                        Dash._x += CellSize;
                    }
                }
                else if (ev.keyCode == 38) {
                    // Up key - rotate
                    var newRotation = (Dash._currentRotation >= 3) ? 0 : Dash._currentRotation + 1;

                    if (engine.isLegalPosition(Dash._that._coords, newRotation, Dash._that._x, Dash._that._y)) {
                        Dash._currentRotation = newRotation;
                    }
                }
                else if (ev.keyCode == 40) {
                    // Down key - move down
                    if (engine.isLegalPosition(Dash._that._coords, Dash._that._currentRotation, Dash._that._x, Dash._that._y + CellSize)) {
                        Dash._y += CellSize;
                    }
                    else {
                        for (var row = 0; row < 4; row++) {//the figure reached the bottom, save its position as set 1 in appopriate cells in the game field matrix
                            for (var col = 0; col < 4; col++) {
                                if (Dash._that._coords[Dash._that._currentRotation][row][col] == 1) {
                                    wiseTetrisGameField._fieldArray[(Dash._that._y / 20) + row - 1][(Dash._that._x / 20) + col] = 1;
                                }
                            }
                        }
                    }
                }
            });
        }
    });

    var TElement = Figure.extend({
        init: function (currentRotation, x0, y0) {
            this._super.init("tElement", CellColors[1], currentRotation, x0, y0);
            this._coords = TElement.initCoords();
            this._that = this;
            return this;
        },

        initCoords: function () {
            return new Array(
                [
                [0, 0, 0, 0],
                [1, 1, 1, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 0, 0],
                [1, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 0, 0],
                [1, 1, 1, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 0]
                ]);
        },

        _addHandlers: function () {
            $(document).keydown(function (ev) {
                if (ev.keyCode == 37) {
                    // Left key
                    if (engine.isLegalPosition(TElement._that._coords, TElement._that._currentRotation, TElement._that._x - CellSize, TElement._that._y)) {
                        TElement._x -= CellSize;
                    }
                }
                else if (ev.keyCode == 39) {
                    // Right key
                    if (engine.isLegalPosition(TElement._that._coords, TElement._that._currentRotation, TElement._that._x + CellSize, TElement._that._y)) {
                        TElement._x += CellSize;
                    }
                }
                else if (ev.keyCode == 38) {
                    // Up key - rotate
                    var newRotation = (TElement._currentRotation >= 3) ? 0 : TElement._currentRotation + 1;

                    if (engine.isLegalPosition(TElement._that._coords, newRotation, TElement._that._x, TElement._that._y)) {
                        TElement._currentRotation = newRotation;
                    }
                }
                else if (ev.keyCode == 40) {
                    // Down key - move down
                    if (engine.isLegalPosition(TElement._that._coords, TElement._that._currentRotation, TElement._that._x, TElement._that._y + CellSize)) {
                        TElement._y += CellSize;
                    }
                    else {
                        for (var row = 0; row < 4; row++) {//the figure reached the bottom, save its position as set 1 in appopriate cells in the game field matrix
                            for (var col = 0; col < 4; col++) {
                                if (TElement._that._coords[TElement._that._currentRotation][row][col] == 1) {
                                    wiseTetrisGameField._fieldArray[(TElement._that._y / 20) + row - 1][(TElement._that._x / 20) + col] = 1;
                                }
                            }
                        }
                    }
                }
            });
        }
    });

    var LElement = Figure.extend({
        init: function (currentRotation, x0, y0) {
            this._super.init("lElement", CellColors[1], currentRotation, x0, y0);
            this._coords = LElement.initCoords();
            this._that = this;
            return this;
        },

        initCoords: function () {
            return new Array(
                [
                [0, 0, 0, 0],
                [1, 1, 1, 0],
                [1, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [1, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 0, 1, 0],
                [1, 1, 1, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 0, 0]
                ]);
        },

        _addHandlers: function () {
            $(document).keydown(function (ev) {
                if (ev.keyCode == 37) {
                    // Left key
                    if (engine.isLegalPosition(LElement._that._coords, LElement._that._currentRotation, LElement._that._x - CellSize, LElement._that._y)) {
                        LElement._x -= CellSize;
                    }
                }
                else if (ev.keyCode == 39) {
                    // Right key
                    if (engine.isLegalPosition(LElement._that._coords, LElement._that._currentRotation, LElement._that._x + CellSize, LElement._that._y)) {
                        LElement._x += CellSize;
                    }
                }
                else if (ev.keyCode == 38) {
                    // Up key - rotate
                    var newRotation = (LElement._currentRotation >= 3) ? 0 : LElement._currentRotation + 1;

                    if (engine.isLegalPosition(LElement._that._coords, newRotation, LElement._that._x, LElement._that._y)) {
                        LElement._currentRotation = newRotation;
                    }
                }
                else if (ev.keyCode == 40) {
                    // Down key - move down
                    if (engine.isLegalPosition(LElement._that._coords, LElement._that._currentRotation, LElement._that._x, LElement._that._y + CellSize)) {
                        LElement._y += CellSize;
                    }
                    else {
                        for (var row = 0; row < 4; row++) {
                            //the figure reached the bottom, save its position as set 1 in appopriate cells in the game field matrix
                            for (var col = 0; col < 4; col++) {
                                if (LElement._that._coords[LElement._that._currentRotation][row][col] == 1) {
                                    wiseTetrisGameField._fieldArray[(LElement._that._y / 20) + row - 1][(LElement._that._x / 20) + col] = 1;
                                }
                            }
                        }
                    }
                }
            });
        }
    });

    var JElement = Figure.extend({
        init: function (currentRotation, x0, y0) {
            this._super.init("jElement", CellColors[1], currentRotation, x0, y0);
            this._coords = JElement.initCoords();
            this._that = this;
            return this;
        },

        initCoords: function () {
            return new Array(
                [
                [1, 0, 0, 0],
                [1, 1, 1, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 1, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 0, 0, 0],
                [1, 1, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [1, 1, 0, 0],
                [0, 0, 0, 0]
                ]);
        },

        _addHandlers: function () {
            $(document).keydown(function (ev) {
                if (ev.keyCode == 37) {
                    // Left key
                    if (engine.isLegalPosition(JElement._that._coords, JElement._that._currentRotation, JElement._that._x - CellSize, JElement._that._y)) {
                        JElement._x -= CellSize;
                    }
                }
                else if (ev.keyCode == 39) {
                    // Right key
                    if (engine.isLegalPosition(JElement._that._coords, JElement._that._currentRotation, JElement._that._x + CellSize, JElement._that._y)) {
                        JElement._x += CellSize;
                    }
                }
                else if (ev.keyCode == 38) {
                    // Up key - rotate
                    var newRotation = (JElement._currentRotation >= 3) ? 0 : JElement._currentRotation + 1;

                    if (engine.isLegalPosition(JElement._that._coords, newRotation, JElement._that._x, JElement._that._y)) {
                        JElement._currentRotation = newRotation;
                    }
                }
                else if (ev.keyCode == 40) {
                    // Down key - move down
                    if (engine.isLegalPosition(JElement._that._coords, JElement._that._currentRotation, JElement._that._x, JElement._that._y + CellSize)) {
                        JElement._y += CellSize;
                    }
                    else {
                        for (var row = 0; row < 4; row++) {//the figure reached the bottom, save its position as set 1 in appopriate cells in the game field matrix
                            for (var col = 0; col < 4; col++) {
                                if (JElement._that._coords[JElement._that._currentRotation][row][col] == 1) {
                                    wiseTetrisGameField._fieldArray[(JElement._that._y / 20) + row - 1][(JElement._that._x / 20) + col] = 1;
                                }
                            }
                        }
                    }
                }
            });
        }
    });

    var ZElement = Figure.extend({
        init: function (currentRotation, x0, y0) {
            this._super.init("zElement", CellColors[1], currentRotation, x0, y0);
            this._coords = ZElement.initCoords();
            this._that = this;
            return this;
        },

        initCoords: function () {
            return new Array(
                [
                [0, 0, 0, 0],
                [1, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 0, 0]
                ], [
                [0, 0, 1, 0],
                [0, 1, 1, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 0, 0, 0],
                [1, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 0, 0]
                ], [
                [0, 0, 1, 0],
                [0, 1, 1, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 0]
                ]);
        },

        _addHandlers: function () {
            $(document).keydown(function (ev) {
                if (ev.keyCode == 37) {
                    // Left key
                    if (engine.isLegalPosition(ZElement._that._coords, ZElement._that._currentRotation, ZElement._that._x - CellSize, ZElement._that._y)) {
                        ZElement._x -= CellSize;
                    }
                }
                else if (ev.keyCode == 39) {
                    // Right key
                    if (engine.isLegalPosition(ZElement._that._coords, ZElement._that._currentRotation, ZElement._that._x + CellSize, ZElement._that._y)) {
                        ZElement._x += CellSize;
                    }
                }
                else if (ev.keyCode == 38) {
                    // Up key - rotate
                    var newRotation = (ZElement._currentRotation >= 3) ? 0 : ZElement._currentRotation + 1;

                    if (engine.isLegalPosition(ZElement._that._coords, newRotation, ZElement._that._x, ZElement._that._y)) {
                        ZElement._currentRotation = newRotation;
                    }
                }
                else if (ev.keyCode == 40) {
                    // Down key - move down
                    if (engine.isLegalPosition(ZElement._that._coords, ZElement._that._currentRotation, ZElement._that._x, ZElement._that._y + CellSize)) {
                        ZElement._y += CellSize;
                    }
                    else {
                        for (var row = 0; row < 4; row++) {//the figure reached the bottom, save its position as set 1 in appopriate cells in the game field matrix
                            for (var col = 0; col < 4; col++) {
                                if (ZElement._that._coords[ZElement._that._currentRotation][row][col] == 1) {
                                    wiseTetrisGameField._fieldArray[(ZElement._that._y / 20) + row - 1][(ZElement._that._x / 20) + col] = 1;
                                }
                            }
                        }
                    }
                }
            });
        }
    });

    var SElement = Figure.extend({
        init: function (currentRotation, x0, y0) {
            this._super.init("sElement", CellColors[1], currentRotation, x0, y0);
            this._coords = SElement.initCoords();
            this._that = this;
            return this;
        },

        initCoords: function () {
            return new Array(
                [
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [1, 1, 0, 0],
                [0, 0, 0, 0]
                ],
                [
                [0, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 0, 0]
                ],
                [
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [1, 1, 0, 0],
                [0, 0, 0, 0]
                ],
                [
                [0, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 0, 0]
                ]);
        },

        _addHandlers: function () {
            $(document).keydown(function (ev) {
                if (ev.keyCode === 37) {
                    // Left
                    if (engine.isLegalPosition(SElement._that._coords, SElement._that._currentRotation, SElement._that._x - CellSize, SElement._that._y)) {
                        SElement._x -= CellSize;
                    }
                }
                if (ev.keyCode === 39) {
                    // Right
                    if (engine.isLegalPosition(SElement._that._coords, SElement._that._currentRotation, SElement._that._x + CellSize, SElement._that._y)) {
                        SElement._x += CellSize;
                    }
                }
                if (ev.keyCode === 38) {
                    // Up key - rotate
                    var newRotation = (SElement._currentRotation >= 3) ? 0 : SElement._currentRotation + 1;
                    if (engine.isLegalPosition(SElement._that._coords, newRotation, SElement._that._x, SElement._that._y)) {
                        SElement._that._currentRotation = newRotation;
                    }
                }
                if (ev.keyCode === 40) {
                    // Down key - move down
                    var newLowerPosition = SElement._that._y + CellSize;
                    if (engine.isLegalPosition(SElement._that._coords, SElement._that._currentRotation, SElement._that._x, newLowerPosition)) {
                        SElement._y += CellSize;
                    }
                    else {
                        for (var row = 0; row < 4; row++) {//the figure reached the bottom, save its position as set 1 in appopriate cells in the game field matrix
                            for (var col = 0; col < 4; col++) {
                                if (SElement._that._coords[SElement._that._currentRotation][row][col] == 1) {
                                    wiseTetrisGameField._fieldArray[(SElement._that._y / 20) + row - 1][(SElement._that._x / 20) + col] = 1;
                                }
                            }
                        }
                    }
                }
            });
        }
    });

    var Square = Figure.extend({
        init: function (currentRotation, x0, y0) {
            this._super.init("square", CellColors[1], currentRotation, x0, y0);
            this._coords = Square.initCoords();
            this._that = this;
            return this;
        },

        initCoords: function () {
            return new Array(
                [
                [0, 1, 1, 0],
                [0, 1, 1, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 1, 0],
                [0, 1, 1, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 1, 0],
                [0, 1, 1, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ], [
                [0, 1, 1, 0],
                [0, 1, 1, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
                ]);
        },

        _addHandlers: function () {
            $(document).keydown(function (ev) {
                if (ev.keyCode == 37) {
                    // Left
                    if (engine.isLegalPosition(Square._that._coords, Square._that._currentRotation, Square._that._x - CellSize, Square._that._y)) {
                        Square._x -= CellSize;
                    }
                }
                else if (ev.keyCode == 39) {
                    // Right
                    if (engine.isLegalPosition(Square._that._coords, Square._that._currentRotation, Square._that._x + CellSize, Square._that._y)) {
                        Square._x += CellSize;
                    }
                }
                else if (ev.keyCode == 38) {
                    // Up key - rotate
                    var newRotation = (Square._currentRotation >= 3) ? 0 : Square._currentRotation + 1;

                    if (engine.isLegalPosition(Square._that._coords, newRotation, Square._that._x, Square._that._y)) {
                        Square._currentRotation = newRotation;
                    }
                }
                else if (ev.keyCode == 40) {
                    // Down key - move down
                    if (engine.isLegalPosition(Square._that._coords, Square._that._currentRotation, Square._that._x, Square._that._y + CellSize)) {
                        Square._y += CellSize;
                    }
                    else {
                        for (var row = 0; row < 4; row++) {//the figure reached the bottom, save its position as set 1 in appopriate cells in the game field matrix
                            for (var col = 0; col < 4; col++) {
                                if (Square._that._coords[Square._that._currentRotation][row][col] == 1) {
                                    wiseTetrisGameField._fieldArray[(Square._that._y / 20) + row - 1][(Square._that._x / 20) + col] = 1;
                                }
                            }
                        }
                    }
                }
            });
        }
    });

    return {
        GameObject: GameObject,
        GameField: GameField,
        Figure: Figure,
        Dash: Dash,
        TElement: TElement,
        LElement: LElement,
        JElement: JElement,
        ZElement: ZElement,
        SElement: SElement,
        Square: Square
    }
})();